﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ca2simulator.shared.Examples
{
    public class LifeExample : IExampleRawData
    {
        public const int SIZE = 800;
        public const int NUMSTATE = 2;
        public const int DEFAULTSTATE = 0;

        public string GetTransferCode()
        {
            string code="";
            #region Code
            using (StreamReader reader = new StreamReader("BasicLifeTransfer.cs"))
            {
                code = reader.ReadToEnd();
            }
            /*
            code =
                "namespace ca2simulator.shared" +
                "{" +
"                    public class BasicLifeTransfer : ITransferFunc" +
"                    {" +

"                        public CellState NextState(Lattice lattice, int r, int c)" +
"                        {" +
"                            CellState state;" +
"                            CellState curState = lattice[r,c].CellState;" +
"                            state.State=curState.State;" +

"                            int liveCnt=0;" +
"                            int maxRow = lattice.Rows;" +
"                            int maxCol = lattice.Columns;" +

"                            for(int i=-1;i<2;i++)" +
"                            {" +
"                                for(int j=-1;j<2;j++)" +
"                                {" +
"                                    if (r + i < 0) r += maxRow;" +
"                                    if (r + i >= maxRow) r -= maxRow;" +

"                                    if (c + j < 0) c += maxCol;" +
"                                    if(c+j>=maxCol) c-=maxCol;" +

"                                    if (i == 0 && j == 0) continue;" +

"                                    // count the number of living cells" +
"                                    if (lattice[r + i, c + j].CellState.State == 1) liveCnt++;" +
"                                }" +
"                            }" +
"                            if (curState.State == 0)" +
"                            {" +
"                                if (liveCnt < 2) state.State = 1;" +
"                                else if (liveCnt > 3) state.State = 1;" +
"                            }" +
"                            else" +
"                            {" +
"                                if (liveCnt == 3) state.State =1;" +
"                            }" +
"                            return state;" +
"                        }" +
"                    }" +
"                }";
             */
            #endregion
            return code;
        }

        public Lattice GetInitialLattice(string name = "")
        {
            Lattice lat = new Lattice(new CellState(), SIZE, SIZE);
            List<CellLocation> pattern;
            CellState aState;
            aState.State=1;

            if ("glider".Equals(name))
            {
                pattern = getPatternByName("glider");
                for (int i = 0; i < SIZE - 5; i+=5)
                {
                    addPattern(lat, pattern, i, 0, aState);
                }
                
            }
            return lat;
        }

        private static void addPattern(Lattice lat, List<CellLocation> pattern, int r, int c, CellState stateToSet)
        {
            Cell cellValue = new Cell();
            cellValue.CellState = stateToSet;
            foreach (CellLocation cs in pattern)
            {
                lat[r + cs.row, c + cs.col] = cellValue;
            }
        }

        private static List<CellLocation> getPatternByName(string pattern)
        {
            List<CellLocation> cells = new List<CellLocation>();
            if ("Glider".Equals(pattern, StringComparison.OrdinalIgnoreCase))
            {
                cells.Add(new CellLocation(0, 1));
                cells.Add(new CellLocation(1, 2));
                cells.Add(new CellLocation(2, 0));
                cells.Add(new CellLocation(2, 1));
                cells.Add(new CellLocation(2, 2));
            }
            else if ("Block".Equals(pattern, StringComparison.OrdinalIgnoreCase))
            {
                cells.Add(new CellLocation(0, 0));
                cells.Add(new CellLocation(0, 1));
                cells.Add(new CellLocation(1, 0));
                cells.Add(new CellLocation(1, 1));
            }

            return cells;

        }

    }
}
